package com.sukaiyi.giteeideaplugin.search;

import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.util.BuildNumber;
import com.sukaiyi.giteeideaplugin.search.repo.ContributorInvocationHandler;
import javassist.*;

public abstract class AbstractSearchEverywhereContributorFactoryJavassistGenerator {

    /**
     * 动态生成class: com.sukaiyi.giteeideaplugin.search.GiteeRepoSearchEverywhereContributorFactory
     * 以兼容 192.5728.98 前后 SearchEverywhereContributorFactory 接口的变化
     */
    public void exec() {
        ClassPool pool = ClassPool.getDefault();
        pool.insertClassPath(new ClassClassPath(ContributorInvocationHandler.class));
        CtClass cc = pool.makeClass(this.factoryClassName());
        try {
            cc.addInterface(pool.get("com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory"));

            CtConstructor cons = new CtConstructor(new CtClass[]{}, cc);
            cons.setBody("{}");
            cc.addConstructor(cons);

            String createContributorSource = "" +
                    "public com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor createContributor(com.intellij.openapi.actionSystem.AnActionEvent initEvent) {\n" +
                    "    com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor contributor = (com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor) java.lang.reflect.Proxy.newProxyInstance(" +
                    "        com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor.class.getClassLoader(), " +
                    "        new Class[]{com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor.class}, " +
                    "        new com.sukaiyi.giteeideaplugin.search.repo.ContributorInvocationHandler()" +
                    "    );\n" +
                    "    return contributor;\n" +
                    "}";

            CtMethod ctMethod = CtMethod.make(createContributorSource, cc);
            cc.addMethod(ctMethod);

            BuildNumber watershed = BuildNumber.fromString("192.5728.98");
            BuildNumber current = ApplicationInfo.getInstance().getBuild();
            if (watershed != null && watershed.compareTo(current) > 0) {
                String createFilterMethod = "" +
                        "public com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFilter createFilter(com.intellij.openapi.actionSystem.AnActionEvent initEvent) {\n" +
                        "    return null;\n" +
                        "}";
                cc.addMethod(CtMethod.make(createFilterMethod, cc));
            }
            cc.toClass(AbstractSearchEverywhereContributorFactoryJavassistGenerator.class.getClassLoader(), null);
        } catch (NotFoundException | CannotCompileException e) {
            e.printStackTrace();
        }
    }

    public abstract String factoryClassName();

    public abstract String proxyClassName();

}
